package com.sunnada.demo.aop;


import com.sunnada.demo.log.OperationTypeEnum;
import com.sunnada.demo.log.TrackLogUtil;
import com.sunnada.demo.log.annotation.LogRecord;
import com.sunnada.demo.log.bean.TrackLog;
import com.sunnada.demo.log.service.TrackLogService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

/**
 * @program: mybatisproject2
 * @description: 切面类，需要约定controller层的方法名
 * @author: 李瑞益
 * @create: 2018-10-28 14:26
 **/
@Aspect
@Component
public class LogAop {

    @Autowired
    private TrackLogService trackLogService;

    /**
     * 使用方法作为切点
     */
    @Pointcut("execution(public * com.sunnada.demo.controller.*.*(..))")
    public void logPointCut() { }

    /**
     * 使用注解作为切点
     */
    @Pointcut("@annotation(logRecord)")
    public void logPointCut2(LogRecord logRecord){}

/**登录操作切点*/
//    @Pointcut("execution(public * com.sunnada.service.serviceimpl.UserServiceImpl.findByName(userName))")//安全框架会报错
    @Pointcut("execution( public * com.sunnada.demo.controller.UserController.login(..)))")
    public void login(){ }

    /**更新操作切点*/
    @Pointcut("execution(public * com.sunnada.demo.controller..update*(..))")
    public void update(){}

    /**新增操作切点*/
    @Pointcut("execution(public * com.sunnada.demo.controller..add*(..))")
    public void add(){}

    /**删除操作切点*/
    @Pointcut("execution(public * com.sunnada.demo.controller..delete*(..))")
    public void delete(){}

    /**
     *
     * @param joinPoint
     * @param logRecord
     * @throws Throwable
     */
/*
   @Before(value="logPointCut() && logPointCut2(logRecord)")
    public void doBefore(JoinPoint joinPoint,LogRecord logRecord) throws Throwable {
        System.out.println("【注解：Before】------------------切面  before");
    }
*/

    /**
     * 登录记录
     * @param
     * @throws Throwable
     */

    @AfterReturning(returning = "returnValue",pointcut = "login()")
    public void doLogin(JoinPoint joinPoint,Object returnValue) throws Throwable {
        System.out.println("【--登录操作日志记录--】");
        //登录操作
        if(returnValue.toString().contains("index")){
            TrackLog log = TrackLogUtil.getTrackLog(OperationTypeEnum.LOGIN,joinPoint,TrackLogUtil.getHttpServletRequest());
            trackLogService.addTrackLog(log);
        }
    }
    /**
     * 删除操作日志记录
     * @param joinPoint
     * @throws Throwable
     */
    @Before(value = "delete()")
    public void doDelete(JoinPoint joinPoint) throws Throwable {
        System.out.println("【--删除操作日志记录--】");
        TrackLog log = TrackLogUtil.getTrackLog(OperationTypeEnum.DELETE,joinPoint,TrackLogUtil.getHttpServletRequest());
        trackLogService.addTrackLog(log);
    }

    /**
     * 更新操作日志记录
     * @param joinPoint
     * @throws Throwable
     */
    @Before(value="update()")
    public void doUpdate(JoinPoint joinPoint) throws Throwable {
        TrackLog log = TrackLogUtil.getTrackLog(OperationTypeEnum.UPDATE,joinPoint,TrackLogUtil.getHttpServletRequest());
        trackLogService.addTrackLog(log);
    }

    /**
     * 新增操作日志记录
     * @param joinPoint
     * @param returnValue
     * @throws Throwable
     */
    @AfterReturning(returning = "returnValue",pointcut = "add()")
    public void doAdd(JoinPoint joinPoint,Object returnValue) throws Throwable {
        System.out.println("【--新增操作日志记录--】");
        TrackLog log = TrackLogUtil.getTrackLog(OperationTypeEnum.ADD,joinPoint,TrackLogUtil.getHttpServletRequest());
        trackLogService.addTrackLog(log);
    }
    /**
     * 当抛出异常时获取异常信息并记录日志
     * @param joinPoint
     * @param e
     */
    @AfterThrowing(pointcut = "logPointCut()",throwing="e")
    public void doException(JoinPoint joinPoint,Throwable e){
        System.out.println("【--异常操作日志记录--】");
        if(e != null) {
            TrackLogUtil.addSystemLog(e);
        }
    }


    /**
     * 最终通知；在所有方法执行后获取信息
     * 获取有LogRecord注解的方法的信息存入日志
     * @param joinpoint 方法对象
    //     * @param logRecord 自定义注解信息
     */
/*
    @After(value = "logPointCut2(logRecord)")
    public void after(JoinPoint joinpoint, LogRecord logRecord) {
        System.out.println("自定义注解信息："+logRecord.value());
        System.out.println("【注解：After】方法最后执行.....");
        addSystemLog(joinpoint,logRecord.value());
    }
*/

    /**
     * 最终通知
     * 在执行方法后添加日志
     * @param joinpoint
     */
 /*   @After(value = "logPointCut()")
    public void after(JoinPoint joinpoint) {
        System.out.println("【注解：After】方法最后执行.....");
        addSystemLog(joinpoint,"");
    }*/

}
